package com.aizuda.easyManagerTool.sdk.docker.api;

import cn.hutool.json.JSONUtil;
import com.aizuda.easyManagerTool.sdk.docker.APIHttpTemplate;
import com.aizuda.easyManagerTool.sdk.docker.DockerConfig;
import com.aizuda.easyManagerTool.sdk.docker.vo.RegistryGetManifestsVO;
import com.aizuda.easyManagerTool.sdk.docker.vo.RegistryImageListVO;
import com.aizuda.easyManagerTool.sdk.docker.vo.RegistryImagesTagListVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;

import java.util.Base64;


@Slf4j
public class DockerRegistryAPI {

    private DockerConfig dockerConfig;
    private static final String IMAGE_LIST = "%s/_catalog";
    private static final String IMAGE_TAG_LIST = "%s/%s/tags/list";

    private static final String MANIFESTS = "%s/%s/manifests/%s";

    private APIHttpTemplate apiHttpTemplate = new APIHttpTemplate();

    public DockerRegistryAPI(DockerConfig dockerConfig) {
        this.dockerConfig = dockerConfig;
    }


    /**
     * 获取库拥有的 tag
     * @param imageName
     * @return
     */
    public RegistryImagesTagListVO getImagesTagList(String imageName){
        try {
            String url = String.format(IMAGE_TAG_LIST ,dockerConfig.getRegistryUrl(),imageName);
            HttpGet httpGet = new HttpGet(url);
            String auth = Base64.getEncoder().encodeToString((dockerConfig.getUserName() + ":" + dockerConfig.getPassword()).getBytes());
            httpGet.setHeader("Authorization", "Basic " + auth);
            String get = apiHttpTemplate.BASE(httpGet);
            return JSONUtil.toBean(get,RegistryImagesTagListVO.class);
        }catch (Exception e){
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    /**
     * 列出所有库
     * @return
     */
    public RegistryImageListVO getImages(){
        try {
            String url = String.format(IMAGE_LIST ,dockerConfig.getRegistryUrl());
            HttpGet httpGet = new HttpGet(url);
            String auth = Base64.getEncoder().encodeToString((dockerConfig.getUserName() + ":" + dockerConfig.getPassword()).getBytes());
            httpGet.setHeader("Authorization", "Basic " + auth);
            String get = apiHttpTemplate.BASE(httpGet);
            return JSONUtil.toBean(get,RegistryImageListVO.class);
        }catch (Exception e){
            throw new IllegalArgumentException(e.getMessage());
        }
    }


    public RegistryGetManifestsVO getManifests(String imageName, String tag){
        try {
            String url = String.format(MANIFESTS ,dockerConfig.getRegistryUrl(),imageName,tag);
            HttpGet httpGet = new HttpGet(url);
            // 不加这个获取不到 digest，没有 digest 则不能使用删除
            httpGet.addHeader("Accept","application/vnd.docker.distribution.manifest.v2+json");
            String auth = Base64.getEncoder().encodeToString((dockerConfig.getUserName() + ":" + dockerConfig.getPassword()).getBytes());
            httpGet.setHeader("Authorization", "Basic " + auth);
            RegistryGetManifestsVO registryGet = apiHttpTemplate.BASE(httpGet,(response,s) -> {
                Header header = response.getFirstHeader("Docker-Content-Digest");
                RegistryGetManifestsVO registryGetManifestsVO = JSONUtil.toBean(s, RegistryGetManifestsVO.class);
                registryGetManifestsVO.setDigest(header.getValue());
                return registryGetManifestsVO;
            });
            return registryGet;
        }catch (Exception e){
            throw new IllegalArgumentException(e.getMessage());
        }
    }


    public String delManifests(String imageName,String tag){
        try {
            String url = String.format(MANIFESTS ,dockerConfig.getRegistryUrl(),imageName,tag);
            HttpDelete httpDelete = new HttpDelete(url);
            String auth = Base64.getEncoder().encodeToString((dockerConfig.getUserName() + ":" + dockerConfig.getPassword()).getBytes());
            httpDelete.setHeader("Authorization", "Basic " + auth);
            String get = apiHttpTemplate.BASE(httpDelete);
            return get;
        }catch (Exception e){
            throw new IllegalArgumentException(e.getMessage());
        }
    }


    public DockerConfig getDockerConfig() {
        return dockerConfig;
    }
}
